#ifndef _LIMIT_H_
#define _LIMIT_H_

#include <defs.h>
#include <stdint.h>
#include <time.h>
#include <vector>
#include <string>

HTTP_SVR_NS_BEGIN

#define MAX_BUCKET_LEN  256
#define MAX_IPSTR_LEN   15

typedef struct tagConfLimit{
    uint16_t      _cfgCount;
    uint16_t      _cfgCycle;
    uint32_t      _limitCap;
    char          _memData[0];

}__attribute__((__aligned__(4)))TConfLimit;

typedef struct tagItemLimit{
    uint16_t            _curAccess;
    time_t              _startTime;
    bool                _bLocked;
    unsigned long int   _lockIp;

}__attribute__((__aligned__(4)))TItemLimit;

using namespace std;

class CLimitPolicy
{
public:
    CLimitPolicy(void);
    virtual ~CLimitPolicy(void);

public:
    static CLimitPolicy* Instance(void);
    static void Destroy(void);
    
public:
    int config_init(const char* xmlfile);
    int check_limit(unsigned long int ip);
    int check_limit_by_qvia(const char* buffer);
    int is_from_proxy(unsigned long int ip);
        
private:
    void* shm_init(const char* filename, int size);
    int record_ip(unsigned long int ip, TItemLimit*& pLimitData);
    uint32_t hash_string(char* arKey, uint32_t nKeyLength);
    bool IsFree(TItemLimit* pLimitData, time_t tTime);
    char* ip_str(unsigned long int ip);
    
private:
    TConfLimit*         _confHeader;

    vector< string >    _blankList;
    
    vector< string >    _proxyList;
};

HTTP_SVR_NS_END

#endif
